<template>
  <div class="game-page">
    <!-- 游戏HUD -->
    <div class="game-hud">
      <div class="hud-left">
        <!-- 计时器 -->
        <div class="timer-display">
          <div class="timer-icon">⏱️</div>
          <div class="timer-content">
            <div class="timer-value">{{ formatTime(gameTimer) }}</div>
            <div class="timer-label">剩余时间</div>
          </div>
        </div>
        
        <!-- 游戏设置 -->
        <button @click="showSettings = !showSettings" class="btn-icon settings-btn">
          ⚙️
        </button>
      </div>

      <div class="hud-center">
        <!-- 游戏状态 -->
        <div class="game-status">
          <h2>涂色抢地盘</h2>
          <p>{{ gameStatus }}</p>
        </div>
      </div>

      <div class="hud-right">
        <!-- 操作提示 -->
        <div class="controls-hint">
          <div class="hint-item">
            <span class="hint-key">WASD</span>
            <span class="hint-action">移动小球</span>
          </div>
          <div class="hint-item">
            <span class="hint-key">空格</span>
            <span class="hint-action">加速冲刺</span>
          </div>
        </div>
      </div>
    </div>

    <!-- 主游戏区域 -->
    <div class="game-main">
      <!-- 左侧面板 -->
      <aside class="game-sidebar left">
        <!-- 玩家信息面板 -->
        <div class="panel players-panel">
          <h3>玩家排名</h3>
          <div class="players-ranking">
            <div
              v-for="(player, index) in sortedPlayers"
              :key="player.id"
              class="player-rank-item"
              :class="{ 'is-current': player.id === currentUserId }"
            >
              <div class="rank-position">{{ index + 1 }}</div>
              <div class="player-color" :style="{ backgroundColor: player.color }"></div>
              <div class="player-info">
                <div class="player-name">{{ player.name }}</div>
                <div class="player-area">{{ player.area }}%</div>
              </div>
              <div class="player-score">{{ player.score }}</div>
            </div>
          </div>
        </div>

        <!-- 迷你地图 -->
        <div class="panel minimap-panel">
          <h3>迷你地图</h3>
          <div class="minimap">
            <canvas
              ref="minimapCanvas"
              class="minimap-canvas"
              width="150"
              height="150"
              @click="handleMinimapClick"
            ></canvas>
            <div class="minimap-cursor" :style="minimapCursorStyle"></div>
          </div>
        </div>
      </aside>

      <!-- 游戏画布区域 -->
      <div class="game-canvas-container">
        <div
          ref="gameCanvas"
          class="game-canvas"
          tabindex="0"
          @keydown="handleKeyDown"
          @keyup="handleKeyUp"
          @mousedown="handleMouseDown"
          @mousemove="handleMouseMove"
          @mouseup="handleMouseUp"
          @mouseleave="handleMouseUp"
        ></div>
        
        <!-- 画布覆盖层（用于显示特效等） -->
        <div class="canvas-overlay">
          <!-- 加速特效 -->
          <div
            v-if="isBoosting"
            class="boost-effect"
          >
            <span class="boost-text">冲刺中!</span>
          </div>
          
          <!-- 连击特效 -->
          <div
            v-if="comboCount > 5"
            class="combo-effect"
            :class="{ 'combo-active': showComboEffect }"
          >
            <span class="combo-text">{{ comboCount }}连击!</span>
            <span class="combo-multiplier">×{{ comboMultiplier }}</span>
          </div>
        </div>
      </div>

      <!-- 右侧面板 -->
      <aside class="game-sidebar right">
        <!-- 游戏统计 -->
        <div class="panel stats-panel">
          <h3>游戏统计</h3>
          <div class="stats-grid">
            <div class="stat-item">
              <div class="stat-value">{{ currentPlayer?.area || 0 }}%</div>
              <div class="stat-label">占领面积</div>
            </div>
            <div class="stat-item">
              <div class="stat-value">{{ paintedCells }}</div>
              <div class="stat-label">移动距离</div>
            </div>
            <div class="stat-item">
              <div class="stat-value">{{ comboCount }}</div>
              <div class="stat-label">连击数</div>
            </div>
            <div class="stat-item">
              <div class="stat-value">{{ currentPlayer?.score || 0 }}</div>
              <div class="stat-label">当前分数</div>
            </div>
          </div>
        </div>

        <!-- 操作按钮 -->
        <div class="panel actions-panel">
          <h3>操作</h3>
          <div class="action-buttons">
            <button @click="resetCombo" class="btn btn-primary">
              重置连击
            </button>
            <button @click="showHelp = true" class="btn btn-secondary">
              游戏帮助
            </button>
            <button @click="leaveGame" class="btn btn-danger">
              离开游戏
            </button>
          </div>
        </div>
      </aside>
    </div>

    <!-- 游戏设置面板 -->
    <div v-if="showSettings" class="settings-overlay" @click="showSettings = false">
      <div class="settings-panel" @click.stop>
        <h3>游戏设置</h3>
        <div class="setting-group">
          <label>音效音量</label>
          <input
            v-model="gameSettings.soundVolume"
            type="range"
            min="0"
            max="100"
            class="range-input"
          />
          <span>{{ gameSettings.soundVolume }}%</span>
        </div>
        <div class="setting-group">
          <label>画质</label>
          <select v-model="gameSettings.quality" class="form-input">
            <option value="low">低</option>
            <option value="medium">中</option>
            <option value="high">高</option>
          </select>
        </div>
        <div class="setting-group">
          <label class="checkbox-label">
            <input v-model="gameSettings.showGrid" type="checkbox" class="checkbox" />
            <span class="checkmark"></span>
            显示网格
          </label>
        </div>
        <div class="setting-group">
          <label class="checkbox-label">
            <input v-model="gameSettings.enableEffects" type="checkbox" class="checkbox" />
            <span class="checkmark"></span>
            特效开启
          </label>
        </div>
        <button @click="showSettings = false" class="btn btn-primary">
          确定
        </button>
      </div>
    </div>

    <!-- 游戏帮助模态框 -->
    <div v-if="showHelp" class="modal-overlay" @click="showHelp = false">
      <div class="modal-content" @click.stop>
        <div class="modal-header">
          <h3>游戏帮助</h3>
          <button @click="showHelp = false" class="close-btn">&times;</button>
        </div>
        <div class="help-content">
          <div class="help-section">
            <h4>🎯 游戏目标</h4>
            <p>控制你的小球在游戏区域内移动，通过经过的路径来占领地盘，占领面积最大的玩家获胜。</p>
          </div>
          <div class="help-section">
            <h4>🎮 操作方法</h4>
            <ul>
              <li><strong>W键:</strong> 向上移动小球</li>
              <li><strong>A键:</strong> 向左移动小球</li>
              <li><strong>S键:</strong> 向下移动小球</li>
              <li><strong>D键:</strong> 向右移动小球</li>
              <li><strong>空格键:</strong> 冲刺加速</li>
            </ul>
          </div>
          <div class="help-section">
            <h4>📊 计分规则</h4>
            <ul>
              <li>小球经过的路径会留下轨迹并占领地盘</li>
              <li>连续移动产生连击效果，获得额外分数</li>
              <li>冲刺状态下移动速度更快，占领效率更高</li>
              <li>最终排名根据占领面积决定</li>
            </ul>
          </div>
          <div class="help-section">
            <h4>🏆 胜利条件</h4>
            <p>游戏结束时占领面积最大的玩家获胜，积分分配为：第一名6分，第二名4分，第三名2分，最后一名扣1分。</p>
          </div>
        </div>
      </div>
    </div>

    <!-- 离开游戏确认弹窗 -->
    <div v-if="showLeaveConfirm" class="modal-overlay">
      <div class="modal-content">
        <div class="modal-header">
          <h3>⚠️ 离开游戏</h3>
        </div>
        <div class="modal-body">
          <p>离开游戏将会扣游戏积分，你确定要离开吗？</p>
        </div>
        <div class="modal-footer">
          <button @click="cancelLeaveGame" class="btn btn-secondary">
            取消
          </button>
          <button @click="confirmLeaveGame" class="btn btn-danger">
            确定离开
          </button>
        </div>
      </div>
    </div>

    <!-- 离开游戏确认弹窗 -->
    <div v-if="showLeaveConfirm" class="modal-overlay" @click="cancelLeaveGame">
      <div class="modal-content leave-confirm-modal" @click.stop>
        <div class="modal-header">
          <h3>⚠️ 离开游戏</h3>
        </div>
        <div class="modal-body">
          <p>离开游戏将会扣游戏积分，你确定要离开吗？</p>
        </div>
        <div class="modal-actions">
          <button @click="cancelLeaveGame" class="btn btn-secondary">
            取消
          </button>
          <button @click="confirmLeaveGame" class="btn btn-danger">
            确定离开
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.game-page {
  min-height: 100vh;
  background: #1a1a1a;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.game-hud {
  background: rgba(0, 0, 0, 0.8);
  backdrop-filter: blur(10px);
  padding: 1rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  position: relative;
  z-index: 100;
}

.hud-left,
.hud-right {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.timer-display {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  background: rgba(255, 255, 255, 0.1);
  padding: 0.75rem 1rem;
  border-radius: 8px;
}

.timer-icon {
  font-size: 1.5rem;
}

.timer-value {
  font-size: 1.5rem;
  font-weight: 700;
  color: #fff;
  font-family: 'Courier New', monospace;
}

.timer-label {
  font-size: 0.8rem;
  color: rgba(255, 255, 255, 0.7);
}

.settings-btn {
  width: 45px;
  height: 45px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.1);
  border: none;
  color: #fff;
  font-size: 1.2rem;
  cursor: pointer;
  transition: all 0.3s ease;
}

.settings-btn:hover {
  background: rgba(255, 255, 255, 0.2);
  transform: scale(1.1);
}

.game-status {
  text-align: center;
  color: #fff;
}

.game-status h2 {
  margin: 0 0 0.25rem 0;
  font-size: 1.5rem;
}

.game-status p {
  margin: 0;
  color: rgba(255, 255, 255, 0.8);
  font-size: 0.9rem;
}

.controls-hint {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.hint-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.8rem;
}

.hint-key {
  background: rgba(255, 255, 255, 0.2);
  padding: 0.25rem 0.5rem;
  border-radius: 4px;
  color: #fff;
  font-weight: 600;
  min-width: 60px;
  text-align: center;
}

.hint-action {
  color: rgba(255, 255, 255, 0.7);
}

.game-main {
  flex: 1;
  display: grid;
  grid-template-columns: 200px 1fr 200px;
  gap: 0.5rem;
  padding: 0.5rem;
  overflow: hidden;
}

.game-sidebar {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.panel {
  background: rgba(255, 255, 255, 0.05);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 8px;
  padding: 0.75rem;
}

.panel h3 {
  color: #fff;
  margin: 0 0 0.75rem 0;
  font-size: 0.9rem;
  font-weight: 600;
}

.players-ranking {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.player-rank-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem;
  background: rgba(255, 255, 255, 0.05);
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  transition: all 0.3s ease;
}

.player-rank-item.is-current {
  border-color: #667eea;
  background: rgba(102, 126, 234, 0.1);
}

.rank-position {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-weight: 700;
  font-size: 0.8rem;
  flex-shrink: 0;
}

.player-color {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  flex-shrink: 0;
}

.player-info {
  flex: 1;
}

.player-name {
  color: #fff;
  font-size: 0.9rem;
  font-weight: 600;
  margin-bottom: 0.25rem;
}

.player-area {
  color: rgba(255, 255, 255, 0.7);
  font-size: 0.8rem;
}

.player-score {
  color: #4facfe;
  font-weight: 600;
  font-size: 0.9rem;
}

.minimap {
  position: relative;
}

.minimap-canvas {
  width: 100%;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 4px;
  cursor: pointer;
}

.minimap-cursor {
  position: absolute;
  width: 20px;
  height: 20px;
  border: 2px solid #ff6b6b;
  border-radius: 50%;
  pointer-events: none;
}

.stats-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.5rem;
}

.stat-item {
  text-align: center;
}

.stat-value {
  font-size: 1.2rem;
  font-weight: 700;
  color: #4facfe;
  margin-bottom: 0.15rem;
}

.stat-label {
  font-size: 0.7rem;
  color: rgba(255, 255, 255, 0.7);
}

.action-buttons {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.action-buttons .btn {
  padding: 0.5rem;
  font-size: 0.8rem;
}

.btn-danger {
  background: linear-gradient(135deg, #ff6b6b 0%, #ee5a52 100%);
  color: white;
}

.btn-danger:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 25px rgba(255, 107, 107, 0.4);
}

.game-canvas-container {
  position: relative;
  background: #2c3e50;
  border-radius: 8px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 80vh;
  width: 100%;
}

.game-canvas {
  border: 1px solid rgba(255, 255, 255, 0.2);
  cursor: crosshair;
  background: #2c3e50;
  outline: none;
  border-radius: 8px;
  max-width: 100%;
  max-height: 100%;
}

.game-canvas:focus {
  border-color: #667eea;
  box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.3);
}

.canvas-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 2rem;
}

.boost-effect {
  text-align: center;
  background: rgba(255, 255, 0, 0.1);
  border: 2px solid #ffff00;
  border-radius: 8px;
  padding: 1rem 2rem;
  backdrop-filter: blur(5px);
}

.boost-text {
  display: block;
  font-size: 1.5rem;
  font-weight: 700;
  color: #ffff00;
  text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
  animation: pulse 0.5s infinite alternate;
}

@keyframes pulse {
  0% { opacity: 0.8; transform: scale(1); }
  100% { opacity: 1; transform: scale(1.1); }
}

.combo-effect {
  text-align: center;
  opacity: 0;
  transform: scale(0.5);
  transition: all 0.5s ease;
}

.combo-effect.combo-active {
  opacity: 1;
  transform: scale(1);
}

.combo-text {
  display: block;
  font-size: 2rem;
  font-weight: 700;
  color: #ff6b6b;
  text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
  margin-bottom: 0.5rem;
}

.combo-multiplier {
  display: block;
  font-size: 1.5rem;
  color: #4facfe;
  text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}

.settings-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.settings-panel {
  background: rgba(30, 30, 30, 0.95);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 12px;
  padding: 2rem;
  min-width: 350px;
}

.settings-panel h3 {
  color: #fff;
  margin-bottom: 1.5rem;
  text-align: center;
}

.setting-group {
  margin-bottom: 1.5rem;
}

.setting-group label {
  display: block;
  color: #fff;
  margin-bottom: 0.5rem;
  font-weight: 600;
}

.range-input {
  width: 100%;
  margin-right: 1rem;
}

.btn-large {
  padding: 1rem 2rem;
  font-size: 1.2rem;
}

.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 2rem;
}

.modal-content {
  background: rgba(30, 30, 30, 0.95);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 12px;
  padding: 2rem;
  max-width: 600px;
  width: 100%;
  max-height: 80vh;
  overflow-y: auto;
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1.5rem;
}

.modal-header h3 {
  color: #fff;
  margin: 0;
}

.close-btn {
  background: none;
  border: none;
  color: #fff;
  font-size: 1.5rem;
  cursor: pointer;
  padding: 0;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  transition: background-color 0.3s ease;
}

.close-btn:hover {
  background: rgba(255, 255, 255, 0.1);
}

.help-content {
  color: rgba(255, 255, 255, 0.9);
}

.help-section {
  margin-bottom: 1.5rem;
}

.help-section h4 {
  color: #4facfe;
  margin-bottom: 0.75rem;
  font-size: 1.1rem;
}

.help-section p {
  line-height: 1.6;
  margin-bottom: 0.5rem;
}

.help-section ul {
  padding-left: 1.5rem;
}

.help-section li {
  margin-bottom: 0.5rem;
  line-height: 1.5;
}

.help-section strong {
  color: #fff;
}

@media (max-width: 1024px) {
  .game-main {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr auto;
  }
  
  .game-sidebar {
    flex-direction: row;
    overflow-x: auto;
  }
  
  .game-sidebar .panel {
    min-width: 200px;
    flex-shrink: 0;
  }
}

@media (max-width: 768px) {
  .game-hud {
    flex-direction: column;
    gap: 1rem;
    padding: 0.75rem;
  }
  
  .hud-left,
  .hud-right {
    justify-content: center;
  }
  
  .controls-hint {
    flex-direction: row;
    gap: 1rem;
  }
  
  .game-main {
    padding: 0.75rem;
  }
  
  .stats-grid {
    grid-template-columns: 1fr;
  }
}

/* 弹窗样式 */
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.4);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  backdrop-filter: blur(2px);
}

.modal-content {
  background: linear-gradient(145deg, #2c3e50 0%, #34495e 50%, #2c3e50 100%);
  border-radius: 20px;
  box-shadow: 
    0 25px 50px rgba(0, 0, 0, 0.4),
    0 0 0 1px rgba(255, 255, 255, 0.1),
    inset 0 1px 0 rgba(255, 255, 255, 0.1);
  min-width: 450px;
  max-width: 520px;
  overflow: hidden;
  animation: modalSlideIn 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  position: relative;
}

.modal-content::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: linear-gradient(90deg, #ff6b6b, #feca57, #48dbfb, #ff9ff3);
  background-size: 400% 400%;
  animation: gradientShift 3s ease infinite;
}

@keyframes gradientShift {
  0%, 100% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
}

@keyframes modalSlideIn {
  0% {
    opacity: 0;
    transform: scale(0.8) translateY(-30px) rotateX(10deg);
  }
  100% {
    opacity: 1;
    transform: scale(1) translateY(0) rotateX(0deg);
  }
}

.modal-header {
  padding: 2rem 2.5rem 1rem;
  text-align: center;
  position: relative;
}

.modal-header h3 {
  color: #ff6b6b;
  font-size: 1.8rem;
  margin: 0;
  font-weight: 700;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
}

.modal-body {
  padding: 1rem 2.5rem 2rem;
  text-align: center;
}

.modal-body p {
  color: rgba(255, 255, 255, 0.95);
  font-size: 1.2rem;
  line-height: 1.6;
  margin: 0;
  font-weight: 400;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}

.modal-actions {
  padding: 0 2.5rem 2.5rem;
  display: flex;
  gap: 1.2rem;
  justify-content: center;
}

.modal-actions .btn {
  flex: 1;
  padding: 1rem 2rem;
  font-size: 1.1rem;
  font-weight: 600;
  border-radius: 12px;
  border: none;
  cursor: pointer;
  transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  position: relative;
  overflow: hidden;
  text-transform: none;
  letter-spacing: 0.5px;
}

.modal-actions .btn::before {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
  transition: left 0.5s;
}

.modal-actions .btn:hover::before {
  left: 100%;
}

.modal-actions .btn-secondary {
  background: linear-gradient(145deg, #6c757d, #5a6268);
  color: #fff;
  box-shadow: 
    0 8px 16px rgba(108, 117, 125, 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.1);
}

.modal-actions .btn-secondary:hover {
  background: linear-gradient(145deg, #5a6268, #495057);
  transform: translateY(-2px);
  box-shadow: 
    0 12px 24px rgba(108, 117, 125, 0.4),
    inset 0 1px 0 rgba(255, 255, 255, 0.2);
}

.modal-actions .btn-danger {
  background: linear-gradient(145deg, #ff6b6b, #ee5a52);
  color: #fff;
  box-shadow: 
    0 8px 16px rgba(255, 107, 107, 0.4),
    inset 0 1px 0 rgba(255, 255, 255, 0.1);
}

.modal-actions .btn-danger:hover {
  background: linear-gradient(145deg, #ff5252, #e53e3e);
  transform: translateY(-2px);
  box-shadow: 
    0 12px 24px rgba(255, 107, 107, 0.5),
    inset 0 1px 0 rgba(255, 255, 255, 0.2);
}

.modal-actions .btn:active {
  transform: translateY(0);
  box-shadow: 
    0 4px 8px rgba(0, 0, 0, 0.2),
    inset 0 1px 0 rgba(255, 255, 255, 0.1);
}

/* 离开游戏确认弹窗特定样式 */
.modal-actions {
  padding: 0 2rem 2rem;
  display: flex;
  gap: 1rem;
  justify-content: center;
}

.modal-actions .btn {
  flex: 1;
  padding: 0.75rem 1.5rem;
  font-size: 1rem;
  font-weight: 500;
  transition: all 0.2s ease;
}

.modal-actions .btn-secondary {
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.modal-actions .btn-secondary:hover {
  background: rgba(255, 255, 255, 0.2);
  transform: translateY(-1px);
}

.modal-actions .btn-danger {
  background: linear-gradient(135deg, #ff4757 0%, #ff3742 100%);
  color: #fff;
  border: none;
}

.modal-actions .btn-danger:hover {
  background: linear-gradient(135deg, #ff3742 0%, #ff2f3a 100%);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(255, 71, 87, 0.3);
}

.leave-confirm-modal {
  border: 1px solid rgba(255, 71, 87, 0.3);
}

.leave-confirm-modal .modal-header h3 {
  color: #ff6b6b;
}
</style>

<script setup>
import { ref, reactive, computed, onMounted, onUnmounted, nextTick } from 'vue'
import { useRouter, useRoute } from 'vue-router'

const router = useRouter()
const route = useRoute()

// DOM引用
const gameCanvas = ref(null)
const minimapCanvas = ref(null)

// Canvas上下文
let canvasCtx = null
let canvas = null

// 游戏状态
const gameTimer = ref(300) // 5分钟 = 300秒
const gameStatus = ref('游戏进行中')
const showSettings = ref(false)
const showHelp = ref(false)
const showLeaveConfirm = ref(false)

// 画布尺寸
const canvasWidth = 1200
const canvasHeight = 800

// 世界地图尺寸（比画布大）
const worldWidth = ref(2400)
const worldHeight = ref(1600)

// 视角系统
const camera = reactive({
  x: 0,
  y: 0,
  width: canvasWidth,
  height: canvasHeight
})

// 拖拽系统
const dragging = reactive({
  isDragging: false,
  startX: 0,
  startY: 0,
  lastCameraX: 0,
  lastCameraY: 0
})

// 当前用户
const currentUserId = ref('player-1')

// 游戏常量
const SPAWN_SAFE_RADIUS = 50 // 出生点安全区域半径
const INVULNERABILITY_TIME = 180 // 复活无敌时间(3秒 * 60fps)
const SEMI_INVULNERABILITY_TIME = 120 // 半无敌时间(2秒 * 60fps)
const MAX_LINE_LENGTH = Math.sqrt(worldWidth.value * worldWidth.value + worldHeight.value * worldHeight.value) * 2.5 // 最大画线长度 - 增加到2.5倍对角线
const DEATH_PENALTY_WINDOW = 600 // 连续死亡判定时间窗口(10秒 * 60fps)
const RESPAWN_DELAY = 480 // 连续死亡惩罚复活延迟(8秒 * 60fps)
const TRAIL_WIDTH = 6 // 轨迹宽度 - 增加到6像素

// 战斗机制常量
const DEATH_RESPAWN_TIME = 180 // 死亡后3秒复活 (3秒 * 60fps)
const TERRITORY_MEMORY_RATIO = 0.2 // 死亡后保留20%历史领地积分
const SPEED_REDUCTION_IN_ENEMY_TERRITORY = 0.8 // 敌方领地内速度减少20%
const SPEED_BOOST_IN_OWN_TERRITORY = 1.15 // 自己领地内速度提升15%
const COLLISION_WARNING_DISTANCE = 3 // 轨迹预警距离

// 游戏开始倒计时
const GAME_START_COUNTDOWN = 3 // 游戏开始前3秒倒计时
const gameStartCountdown = ref(GAME_START_COUNTDOWN)
const gameStarted = ref(false)

// 游戏数据
const players = ref([
  {
    id: 'player-1',
    name: '我自己',
    color: '#ff6b6b',
    area: 0,
    score: 0,
    isAlive: true,
    isDead: false,
    respawnTimer: 0,
    maxHistoryArea: 0, // 历史最大领地面积
    territoryMemoryScore: 0, // 领地记忆积分
    ball: {
      x: 200,
      y: 200,
      radius: 8,
      speed: 4,
      baseSpeed: 4, // 基础速度，用于领地速度调整
      isDrawing: false,
      currentPath: [],
      trail: [],
      isInvulnerable: false,
      invulnerabilityTime: 0,
      semiInvulnerabilityTime: 0,
      lastDeathTime: 0,
      deathCount: 0,
      pathWarning: false, // 轨迹预警状态
      warningCheckCounter: 0 // 预警检查计数器
    },
    spawnPoint: { x: 200, y: 200 },
    territory: [], // 已占领的领地（多边形数组）
    safeZone: { x: 200, y: 200, radius: SPAWN_SAFE_RADIUS } // 出生点安全区
  },
  {
    id: 'player-2',
    name: '玩家2',
    color: '#4ecdc4',
    area: 0,
    score: 0,
    isAlive: true,
    isDead: false,
    respawnTimer: 0,
    maxHistoryArea: 0,
    territoryMemoryScore: 0,
    ball: {
      x: 2200,
      y: 200,
      radius: 8,
      speed: 3,
      baseSpeed: 3,
      isDrawing: false,
      currentPath: [],
      trail: [],
      isInvulnerable: false,
      invulnerabilityTime: 0,
      semiInvulnerabilityTime: 0,
      lastDeathTime: 0,
      deathCount: 0,
      pathWarning: false,
      warningCheckCounter: 0
    },
    spawnPoint: { x: 2200, y: 200 },
    territory: [],
    safeZone: { x: 2200, y: 200, radius: SPAWN_SAFE_RADIUS }
  },
  {
    id: 'player-3',
    name: '玩家3',
    color: '#45b7d1',
    area: 0,
    score: 0,
    isAlive: true,
    isDead: false,
    respawnTimer: 0,
    maxHistoryArea: 0,
    territoryMemoryScore: 0,
    ball: {
      x: 2200,
      y: 1400,
      radius: 8,
      speed: 3,
      baseSpeed: 3,
      isDrawing: false,
      currentPath: [],
      trail: [],
      isInvulnerable: false,
      invulnerabilityTime: 0,
      semiInvulnerabilityTime: 0,
      lastDeathTime: 0,
      deathCount: 0,
      pathWarning: false
    },
    spawnPoint: { x: 2200, y: 1400 },
    territory: [],
    safeZone: { x: 2200, y: 1400, radius: SPAWN_SAFE_RADIUS }
  },
  {
    id: 'player-4',
    name: '玩家4',
    color: '#f7b731',
    area: 0,
    score: 0,
    isAlive: true,
    isDead: false,
    respawnTimer: 0,
    maxHistoryArea: 0,
    territoryMemoryScore: 0,
    ball: {
      x: 200,
      y: 1400,
      radius: 8,
      speed: 3,
      baseSpeed: 3,
      isDrawing: false,
      currentPath: [],
      trail: [],
      isInvulnerable: false,
      invulnerabilityTime: 0,
      semiInvulnerabilityTime: 0,
      lastDeathTime: 0,
      deathCount: 0,
      pathWarning: false
    },
    spawnPoint: { x: 200, y: 1400 },
    territory: [],
    safeZone: { x: 200, y: 1400, radius: SPAWN_SAFE_RADIUS }
  }
])

// 键盘输入状态
const keys = reactive({
  w: false,
  a: false,
  s: false,
  d: false,
  space: false
})

// 游戏状态
const isBoosting = ref(false)
const boostCooldown = ref(0)
const maxBoostTime = 60
const currentBoostTime = ref(0)

// 游戏统计
const paintedCells = ref(0)
const comboCount = ref(0)
const comboMultiplier = ref(1)
const showComboEffect = ref(false)

// 游戏设置
const gameSettings = reactive({
  soundVolume: 80,
  quality: 'medium',
  showGrid: true,
  enableEffects: true
})

// 计算属性
const sortedPlayers = computed(() => {
  return [...players.value].sort((a, b) => b.area - a.area)
})

const currentPlayer = computed(() => {
  return players.value.find(p => p.id === currentUserId.value)
})

const minimapCursorStyle = computed(() => {
  return {
    left: '50%',
    top: '50%',
    transform: 'translate(-50%, -50%)'
  }
})

// 定时器
let gameInterval = null
let gameLoop = null

// ============= 几何算法函数 =============

// 点在多边形内检测
const pointInPolygon = (point, polygon) => {
  let inside = false
  for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
    if (((polygon[i].y > point.y) !== (polygon[j].y > point.y)) &&
        (point.x < (polygon[j].x - polygon[i].x) * (point.y - polygon[i].y) / (polygon[j].y - polygon[i].y) + polygon[i].x)) {
      inside = !inside
    }
  }
  return inside
}

// 点在圆内检测
const pointInCircle = (point, center, radius) => {
  const dx = point.x - center.x
  const dy = point.y - center.y
  return dx * dx + dy * dy <= radius * radius
}

// 计算多边形面积
const calculatePolygonArea = (polygon) => {
  if (polygon.length < 3) return 0
  let area = 0
  for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
    area += (polygon[j].x + polygon[i].x) * (polygon[j].y - polygon[i].y)
  }
  return Math.abs(area) / 2
}

// 计算路径长度
const calculatePathLength = (path) => {
  if (path.length < 2) return 0
  let length = 0
  for (let i = 1; i < path.length; i++) {
    const dx = path[i].x - path[i-1].x
    const dy = path[i].y - path[i-1].y
    length += Math.sqrt(dx * dx + dy * dy)
  }
  return length
}

// ============= 游戏逻辑函数 =============

// ========= 战斗机制函数 =========

// 线段相交检测（用于精确碰撞检测）
const linesIntersect = (line1Start, line1End, line2Start, line2End) => {
  const det = (line1End.x - line1Start.x) * (line2End.y - line2Start.y) - (line2End.x - line2Start.x) * (line1End.y - line1Start.y)
  if (det === 0) return false // 平行线
  
  const lambda = ((line2End.y - line2Start.y) * (line2End.x - line1Start.x) + (line2Start.x - line2End.x) * (line2End.y - line1Start.y)) / det
  const gamma = ((line1Start.y - line1End.y) * (line2End.x - line1Start.x) + (line1End.x - line1Start.x) * (line2End.y - line1Start.y)) / det
  
  return (0 < lambda && lambda < 1) && (0 < gamma && gamma < 1)
}

// 点到线段的最短距离
const pointToLineDistance = (point, lineStart, lineEnd) => {
  const A = point.x - lineStart.x
  const B = point.y - lineStart.y
  const C = lineEnd.x - lineStart.x
  const D = lineEnd.y - lineStart.y
  
  const dot = A * C + B * D
  const lenSq = C * C + D * D
  let param = -1
  if (lenSq !== 0) param = dot / lenSq
  
  let xx, yy
  if (param < 0) {
    xx = lineStart.x
    yy = lineStart.y
  } else if (param > 1) {
    xx = lineEnd.x
    yy = lineEnd.y
  } else {
    xx = lineStart.x + param * C
    yy = lineStart.y + param * D
  }
  
  const dx = point.x - xx
  const dy = point.y - yy
  return Math.sqrt(dx * dx + dy * dy)
}

// 检查轨迹碰撞（优化性能）
const checkTrajectoryCollision = (movingPlayer, targetPlayer) => {
  if (!movingPlayer.ball.isDrawing || movingPlayer.ball.currentPath.length < 2) return false
  if (!targetPlayer.ball.isDrawing || targetPlayer.ball.currentPath.length < 2) return false
  
  // 性能优化：只检查路径的最近部分
  const checkLength1 = Math.min(5, movingPlayer.ball.currentPath.length - 1)
  const checkLength2 = Math.min(5, targetPlayer.ball.currentPath.length - 1)
  
  const start1 = Math.max(0, movingPlayer.ball.currentPath.length - checkLength1 - 1)
  const start2 = Math.max(0, targetPlayer.ball.currentPath.length - checkLength2 - 1)
  
  // 检查两个玩家的轨迹是否相交
  for (let i = start1; i < movingPlayer.ball.currentPath.length - 1; i++) {
    for (let j = start2; j < targetPlayer.ball.currentPath.length - 1; j++) {
      if (linesIntersect(
        movingPlayer.ball.currentPath[i],
        movingPlayer.ball.currentPath[i + 1],
        targetPlayer.ball.currentPath[j],
        targetPlayer.ball.currentPath[j + 1]
      )) {
        return true
      }
    }
  }
  return false
}

// 检查玩家球体是否碰撞轨迹（优化性能）
const checkBallTrajectoryCollision = (player, targetPlayer) => {
  if (!targetPlayer.ball.isDrawing || targetPlayer.ball.currentPath.length < 2) return false
  
  const ballPos = { x: player.ball.x, y: player.ball.y }
  
  // 性能优化：只检查轨迹的最近部分
  const checkLength = Math.min(10, targetPlayer.ball.currentPath.length - 1)
  const startIndex = Math.max(0, targetPlayer.ball.currentPath.length - checkLength - 1)
  
  // 检查球体是否与目标玩家的轨迹碰撞
  for (let i = startIndex; i < targetPlayer.ball.currentPath.length - 1; i++) {
    const distance = pointToLineDistance(
      ballPos,
      targetPlayer.ball.currentPath[i],
      targetPlayer.ball.currentPath[i + 1]
    )
    if (distance <= player.ball.radius + TRAIL_WIDTH) {
      return true
    }
  }
  return false
}

// 轨迹预警系统（优化性能）
const checkTrajectoryWarning = (player) => {
  if (!player.ball.isDrawing || player.ball.currentPath.length < 2) {
    player.ball.pathWarning = false
    return
  }
  
  // 性能优化：只检查当前玩家的预警，且限制检查频率
  if (player.id !== currentUserId.value) {
    return
  }
  
  // 限制预警检查频率（每5帧检查一次）
  if (!player.ball.warningCheckCounter) player.ball.warningCheckCounter = 0
  player.ball.warningCheckCounter++
  if (player.ball.warningCheckCounter % 5 !== 0) {
    return
  }
  
  let hasWarning = false
  
  // 只检查路径的最后几个点，减少计算量
  const checkLength = Math.min(10, player.ball.currentPath.length - 1)
  const startIndex = Math.max(0, player.ball.currentPath.length - checkLength - 1)
  
  // 检查是否有其他玩家接近自己的轨迹
  players.value.forEach(otherPlayer => {
    if (otherPlayer.id === player.id || !otherPlayer.isAlive || otherPlayer.isDead) return
    
    const otherBallPos = { x: otherPlayer.ball.x, y: otherPlayer.ball.y }
    
    // 只检查轨迹的最近部分
    for (let i = startIndex; i < player.ball.currentPath.length - 1; i++) {
      const distance = pointToLineDistance(
        otherBallPos,
        player.ball.currentPath[i],
        player.ball.currentPath[i + 1]
      )
      if (distance <= COLLISION_WARNING_DISTANCE) {
        hasWarning = true
        return // 跳出内层循环
      }
    }
  })
  
  player.ball.pathWarning = hasWarning
}

// 玩家死亡处理
const killPlayer = (playerId, killerId = null) => {
  const player = players.value.find(p => p.id === playerId)
  if (!player || !player.isAlive || player.isDead) return
  
  console.log(`玩家 ${player.name} 被杀死`)
  
  // 记录历史最大领地面积
  const currentArea = calculatePlayerTotalArea(playerId)
  if (currentArea > player.maxHistoryArea) {
    player.maxHistoryArea = currentArea
  }
  
  // 计算领地记忆积分（保留20%的最大历史领地面积）
  player.territoryMemoryScore = Math.floor(player.maxHistoryArea * TERRITORY_MEMORY_RATIO)
  
  // 死亡状态设置
  player.isDead = true
  player.isAlive = false
  player.respawnTimer = DEATH_RESPAWN_TIME
  
  // 清除当前轨迹
  player.ball.isDrawing = false
  player.ball.currentPath = []
  player.ball.pathWarning = false
  
  // 重置领地为出生点安全区（清除所有占领的领地）
  player.territory = []
  player.area = Math.PI * SPAWN_SAFE_RADIUS * SPAWN_SAFE_RADIUS
  player.score = player.territoryMemoryScore
  
  // 重置位置到出生点
  player.ball.x = player.spawnPoint.x
  player.ball.y = player.spawnPoint.y
  
  // 记录死亡时间和次数
  player.ball.lastDeathTime = Date.now()
  player.ball.deathCount++
}

// 玩家复活处理
const respawnPlayer = (playerId) => {
  const player = players.value.find(p => p.id === playerId)
  if (!player || !player.isDead) return
  
  console.log(`玩家 ${player.name} 复活`)
  
  // 恢复生存状态
  player.isDead = false
  player.isAlive = true
  player.respawnTimer = 0
  
  // 设置复活无敌时间
  player.ball.isInvulnerable = true
  player.ball.invulnerabilityTime = INVULNERABILITY_TIME
  
  // 重置到出生点
  player.ball.x = player.spawnPoint.x
  player.ball.y = player.spawnPoint.y
}

// 检查玩家是否在敌方领地内
const getPlayerTerritoryStatus = (playerId, position) => {
  const player = players.value.find(p => p.id === playerId)
  if (!player) return { inOwnTerritory: false, inEnemyTerritory: false, enemyPlayerId: null }
  
  // 检查是否在自己领地内
  const inOwnTerritory = isPointInOwnTerritory(position, playerId)
  
  // 检查是否在敌方领地内
  let inEnemyTerritory = false
  let enemyPlayerId = null
  
  for (const otherPlayer of players.value) {
    if (otherPlayer.id === playerId || !otherPlayer.isAlive) continue
    
    if (isPointInOwnTerritory(position, otherPlayer.id)) {
      inEnemyTerritory = true
      enemyPlayerId = otherPlayer.id
      break
    }
  }
  
  return { inOwnTerritory, inEnemyTerritory, enemyPlayerId }
}

// 调整玩家速度（基于领地状态）
const adjustPlayerSpeed = (player) => {
  const position = { x: player.ball.x, y: player.ball.y }
  const territoryStatus = getPlayerTerritoryStatus(player.id, position)
  
  if (territoryStatus.inOwnTerritory) {
    // 在自己领地内，速度提升15%
    player.ball.speed = player.ball.baseSpeed * SPEED_BOOST_IN_OWN_TERRITORY
  } else if (territoryStatus.inEnemyTerritory) {
    // 在敌方领地内，速度降低20%
    player.ball.speed = player.ball.baseSpeed * SPEED_REDUCTION_IN_ENEMY_TERRITORY
  } else {
    // 在中性区域，正常速度
    player.ball.speed = player.ball.baseSpeed
  }
}

// 检查是否可以在指定位置开始画线
const canStartDrawingAt = (playerId, position) => {
  const territoryStatus = getPlayerTerritoryStatus(playerId, position)
  
  // 不能在敌方领地内开始画线
  if (territoryStatus.inEnemyTerritory) {
    return false
  }
  
  return true
}

// 计算玩家总领地面积
const calculatePlayerTotalArea = (playerId) => {
  const player = players.value.find(p => p.id === playerId)
  if (!player) return 0
  
  let totalArea = Math.PI * SPAWN_SAFE_RADIUS * SPAWN_SAFE_RADIUS // 出生点安全区域面积
  
  // 计算所有领地面积
  for (const territory of player.territory) {
    totalArea += calculatePolygonArea(territory)
  }
  
  return totalArea
}

// ========= 原有函数 =========

// 检查点是否在玩家自己的领地内
const isPointInOwnTerritory = (point, playerId) => {
  const player = players.value.find(p => p.id === playerId)
  if (!player) return false
  
  // 检查是否在出生点安全区域
  if (pointInCircle(point, player.spawnPoint, SPAWN_SAFE_RADIUS)) {
    return true
  }
  
  // 检查是否在已占领的领地
  for (const territory of player.territory) {
    if (territory.type === 'filled' && territory.bounds) {
      // 对于填充类型的领土，先检查边界框再检查像素
      const bounds = territory.bounds
      if (point.x >= bounds.minX && point.x <= bounds.maxX && 
          point.y >= bounds.minY && point.y <= bounds.maxY) {
        // 使用轮廓进行快速检测而不是像素级检测
        if (territory.outline && pointInPolygon(point, territory.outline)) {
          return true
        }
      }
    } else if (territory.type === 'path' && territory.points) {
      // 对于路径类型的领土
      if (pointInPolygon(point, territory.points)) {
        return true
      }
    } else if (Array.isArray(territory)) {
      // 兼容旧格式
      if (pointInPolygon(point, territory)) {
        return true
      }
    }
  }
  
  return false
}

// 检查点是否在任何玩家的领地内
const isPointInAnyTerritory = (point) => {
  for (const player of players.value) {
    // 检查是否在出生点安全区域
    if (pointInCircle(point, player.spawnPoint, SPAWN_SAFE_RADIUS)) {
      return { inTerritory: true, ownerId: player.id }
    }
    
    // 检查是否在已占领的领地
    for (const territory of player.territory) {
      if (pointInPolygon(point, territory)) {
        return { inTerritory: true, ownerId: player.id }
      }
    }
  }
  
  return { inTerritory: false, ownerId: null }
}

// 完成圈地
// 寻找沿着领土边界的路径
// 高效渲染填充领土
const renderFilledTerritoryOptimized = (ctx, territory, color) => {
  if (!territory.pixels || territory.pixels.length === 0) return
  
  // 设置填充样式
  ctx.fillStyle = color
  
  // 按行分组像素以提高效率
  const rowGroups = {}
  territory.pixels.forEach(pixel => {
    const y = Math.floor(pixel.y)
    const x = Math.floor(pixel.x)
    if (!rowGroups[y]) {
      rowGroups[y] = []
    }
    rowGroups[y].push(x)
  })
  
  // 绘制连续的矩形段
  Object.keys(rowGroups).forEach(y => {
    const yPos = parseInt(y)
    const xValues = [...new Set(rowGroups[y])].sort((a, b) => a - b) // 去重并排序
    
    if (xValues.length === 0) return
    
    let startX = xValues[0]
    let endX = xValues[0]
    
    for (let i = 1; i < xValues.length; i++) {
      if (xValues[i] === endX + 1) {
        // 连续像素，扩展范围
        endX = xValues[i]
      } else {
        // 绘制当前连续段
        ctx.fillRect(startX, yPos, endX - startX + 1, 1)
        startX = xValues[i]
        endX = xValues[i]
      }
    }
    
    // 绘制最后一段
    ctx.fillRect(startX, yPos, endX - startX + 1, 1)
  })
  
  // 为了确保完全覆盖，再绘制一层稍微透明的覆盖
  ctx.globalAlpha = 0.8
  ctx.fillStyle = color
  
  // 绘制轮廓填充以确保边缘完整
  if (territory.outline && territory.outline.length >= 3) {
    ctx.beginPath()
    ctx.moveTo(territory.outline[0].x, territory.outline[0].y)
    for (let i = 1; i < territory.outline.length; i++) {
      ctx.lineTo(territory.outline[i].x, territory.outline[i].y)
    }
    ctx.closePath()
    ctx.fill()
  }
  
  // 恢复透明度
  ctx.globalAlpha = 1.0
}

// 创建填充的领土区域
const createFilledTerritory = (path, player) => {
  if (path.length < 3) return null
  
  // 获取边界框
  const bbox = getBoundingBox(path)
  if (!bbox) return null
  
  // 确保边界框合理
  const width = bbox.maxX - bbox.minX
  const height = bbox.maxY - bbox.minY
  
  if (width <= 0 || height <= 0) {
    return { type: 'path', points: path }
  }
  
  // 限制区域大小以避免性能问题
  const maxArea = 30000 // 增加到30000像素
  if (width * height > maxArea) {
    console.log('区域太大，使用简化填充')
    return { type: 'path', points: path }
  }
  
  console.log(`创建填充区域，大小: ${width}x${height}`)
  
  // 使用扫描线算法进行完整填充
  const filledPixels = []
  
  // 逐行扫描
  for (let y = Math.floor(bbox.minY); y <= Math.ceil(bbox.maxY); y++) {
    const intersections = []
    
    // 找到扫描线与多边形边的所有交点
    for (let i = 0; i < path.length; i++) {
      const p1 = path[i]
      const p2 = path[(i + 1) % path.length]
      
      // 检查边是否与扫描线相交
      if ((p1.y <= y && p2.y > y) || (p1.y > y && p2.y <= y)) {
        // 计算交点的x坐标
        const x = p1.x + (y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y)
        intersections.push(x)
      }
    }
    
    // 排序交点
    intersections.sort((a, b) => a - b)
    
    // 填充每对交点之间的像素
    for (let i = 0; i < intersections.length; i += 2) {
      if (i + 1 < intersections.length) {
        const startX = Math.floor(intersections[i])
        const endX = Math.ceil(intersections[i + 1])
        
        for (let x = startX; x <= endX; x++) {
          filledPixels.push({ x, y })
        }
      }
    }
  }
  
  // 如果扫描线算法没有足够的像素，回退到点在多边形内算法
  if (filledPixels.length < 10) {
    console.log('扫描线算法结果不理想，使用点在多边形内算法')
    const backupPixels = []
    
    for (let x = Math.floor(bbox.minX); x <= Math.ceil(bbox.maxX); x++) {
      for (let y = Math.floor(bbox.minY); y <= Math.ceil(bbox.maxY); y++) {
        if (pointInPolygon({x, y}, path)) {
          backupPixels.push({ x, y })
        }
      }
    }
    
    console.log(`备用算法填充像素数量: ${backupPixels.length}`)
    
    return {
      type: 'filled',
      pixels: backupPixels,
      bounds: bbox,
      outline: path
    }
  }
  
  console.log(`扫描线算法填充像素数量: ${filledPixels.length}`)
  
  return {
    type: 'filled',
    pixels: filledPixels,
    bounds: bbox,
    outline: path
  }
}

const findBoundaryPath = (startPoint, endPoint, player) => {
  console.log('寻找边界路径从', startPoint, '到', endPoint)
  
  // 收集所有领土边界点（包括出生点周围的圆形边界）
  const allBoundaryPoints = []
  
  // 添加出生点周围的圆形边界点
  const spawnBoundary = generateCircleBoundary(player.spawnPoint, SPAWN_SAFE_RADIUS)
  allBoundaryPoints.push(...spawnBoundary)
  
  // 添加所有现有领土的边界点
  player.territory.forEach(territory => {
    if (territory.type === 'filled' && territory.outline) {
      allBoundaryPoints.push(...territory.outline)
    } else if (territory.type === 'path' && territory.points) {
      allBoundaryPoints.push(...territory.points)
    } else if (Array.isArray(territory)) {
      allBoundaryPoints.push(...territory)
    }
  })
  
  console.log('总边界点数:', allBoundaryPoints.length)
  
  if (allBoundaryPoints.length < 2) {
    // 如果没有足够的边界点，返回直线连接
    return [endPoint, startPoint]
  }
  
  // 使用简化的路径查找算法
  const boundaryPath = findShortestBoundaryPath(startPoint, endPoint, allBoundaryPoints)
  
  console.log('找到边界路径长度:', boundaryPath.length)
  return boundaryPath
}

// 生成圆形边界点
const generateCircleBoundary = (center, radius) => {
  const points = []
  const numPoints = 32 // 圆形分成32段
  
  for (let i = 0; i < numPoints; i++) {
    const angle = (i * 2 * Math.PI) / numPoints
    const x = center.x + radius * Math.cos(angle)
    const y = center.y + radius * Math.sin(angle)
    points.push({ x, y })
  }
  
  return points
}

// 查找最短边界路径
const findShortestBoundaryPath = (start, end, boundaryPoints) => {
  // 如果没有边界点，直接连接
  if (boundaryPoints.length === 0) {
    return [end, start]
  }
  
  // 找到距离起点和终点最近的边界点
  let closestToStart = null
  let closestToEnd = null
  let minStartDist = Infinity
  let minEndDist = Infinity
  let startIndex = -1
  let endIndex = -1
  
  boundaryPoints.forEach((point, index) => {
    const startDist = Math.sqrt((point.x - start.x) ** 2 + (point.y - start.y) ** 2)
    const endDist = Math.sqrt((point.x - end.x) ** 2 + (point.y - end.y) ** 2)
    
    if (startDist < minStartDist) {
      minStartDist = startDist
      closestToStart = point
      startIndex = index
    }
    
    if (endDist < minEndDist) {
      minEndDist = endDist
      closestToEnd = point
      endIndex = index
    }
  })
  
  if (!closestToStart || !closestToEnd || startIndex === endIndex) {
    return [end, start]
  }
  
  // 构建沿着边界的路径
  const path = [end]
  
  // 如果距离很近，直接连接
  if (minEndDist < 10) {
    path.push(closestToEnd)
  }
  
  // 沿着边界从终点到起点
  if (startIndex !== endIndex) {
    const step = startIndex > endIndex ? 1 : -1
    let current = endIndex
    
    // 限制路径长度，避免过度复杂
    let maxSteps = Math.min(Math.abs(startIndex - endIndex), 20)
    
    while (maxSteps > 0 && current !== startIndex) {
      current += step
      if (current >= boundaryPoints.length) current = 0
      if (current < 0) current = boundaryPoints.length - 1
      
      path.push({ ...boundaryPoints[current] })
      maxSteps--
    }
  }
  
  // 如果距离很近，添加起点附近的边界点
  if (minStartDist < 10) {
    path.push(closestToStart)
  }
  
  path.push(start)
  
  return path
}

const completeTerritory = (playerId, path) => {
  const player = players.value.find(p => p.id === playerId)
  if (!player || path.length < 3) return
  
  console.log(`玩家 ${player.name} 完成圈地，轨迹长度: ${path.length}`)
  
  // 获取轨迹的起点和终点
  const startPoint = path[0]
  const endPoint = path[path.length - 1]
  
  // 找到连接起点和终点的领土边界路径
  const boundaryPath = findBoundaryPath(startPoint, endPoint, player)
  
  // 组合玩家轨迹和边界路径形成完整的封闭区域
  const completePath = [...path, ...boundaryPath]
  console.log(`完整封闭路径长度: ${completePath.length}`)
  
  // 使用洪水填充算法填充封闭区域
  const filledTerritory = createFilledTerritory(completePath, player)
  
  if (filledTerritory) {
    // 添加到领土数组
    player.territory.push(filledTerritory)
    console.log(`新增领土，总领土数量: ${player.territory.length}`)
  }
  
  // 更新玩家面积和分数
  updatePlayerStats(playerId)
  
  // 更新连击
  if (playerId === currentUserId.value) {
    updateCombo()
  }
  
  // 清空当前路径
  player.ball.currentPath = []
  player.ball.isDrawing = false
}

// 渲染洪水填充的领土（优化版本）
function renderFloodFillTerritory(ctx, territory, color) {
  if (!territory.filledPixels || territory.filledPixels.length === 0) return
  
  // 设置填充颜色
  ctx.fillStyle = color
  
  // 批量绘制矩形以提高性能
  ctx.beginPath()
  
  // 按行分组像素点，减少绘制调用次数
  const pixelRows = {}
  territory.filledPixels.forEach(point => {
    if (!pixelRows[point.y]) {
      pixelRows[point.y] = []
    }
    pixelRows[point.y].push(point.x)
  })
  
  // 为每行绘制连续的矩形
  Object.keys(pixelRows).forEach(y => {
    const yPos = parseInt(y)
    const xPoints = pixelRows[y].sort((a, b) => a - b)
    
    let startX = xPoints[0]
    let endX = xPoints[0]
    
    for (let i = 1; i < xPoints.length; i++) {
      if (xPoints[i] === endX + 1) {
        // 连续像素
        endX = xPoints[i]
      } else {
        // 绘制当前连续段
        ctx.rect(startX, yPos, endX - startX + 1, 1)
        startX = xPoints[i]
        endX = xPoints[i]
      }
    }
    
    // 绘制最后一段
    ctx.rect(startX, yPos, endX - startX + 1, 1)
  })
  
  ctx.fill()
}

const createTerritoryWithFloodFill = (path, spawnPoint, playerId) => {
  if (path.length < 3) return null
  
  // 获取边界框
  const bbox = getBoundingBox(path)
  
  // 如果区域太大，回退到传统多边形方法
  const area = (bbox.maxX - bbox.minX) * (bbox.maxY - bbox.minY)
  if (area > 50000) { // 大于50000像素的区域使用传统方法
    return {
      type: 'polygon',
      path: [...path],
      bounds: bbox,
      playerId: playerId
    }
  }
  
  const filledPixels = []
  
  // 使用优化的射线投射算法
  const isPointInPolygon = (point, polygon) => {
    let inside = false
    for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
      const xi = polygon[i].x, yi = polygon[i].y
      const xj = polygon[j].x, yj = polygon[j].y
      
      if (((yi > point.y) !== (yj > point.y)) &&
          (point.x < (xj - xi) * (point.y - yi) / (yj - yi) + xi)) {
        inside = !inside
      }
    }
    return inside
  }
  
  // 使用适应性步长
  const step = Math.max(1, Math.floor(Math.sqrt(area) / 100))
  
  for (let x = Math.floor(bbox.minX); x <= Math.ceil(bbox.maxX); x += step) {
    for (let y = Math.floor(bbox.minY); y <= Math.ceil(bbox.maxY); y += step) {
      if (isPointInPolygon({x, y}, path)) {
        // 填充步长大小的区域
        for (let dx = 0; dx < step; dx++) {
          for (let dy = 0; dy < step; dy++) {
            const px = x + dx
            const py = y + dy
            if (px <= bbox.maxX && py <= bbox.maxY) {
              filledPixels.push({ x: px, y: py })
            }
          }
        }
      }
    }
  }
  
  return {
    type: 'flood_fill',
    filledPixels: filledPixels,
    bounds: bbox,
    playerId: playerId
  }
}

// 获取路径的边界框
const getBoundingBox = (path) => {
  if (path.length === 0) return null
  
  let minX = path[0].x, maxX = path[0].x
  let minY = path[0].y, maxY = path[0].y
  
  for (const point of path) {
    minX = Math.min(minX, point.x)
    maxX = Math.max(maxX, point.x)
    minY = Math.min(minY, point.y)
    maxY = Math.max(maxY, point.y)
  }
  
  return { minX, maxX, minY, maxY }
}

// 更新玩家统计
const updatePlayerStats = (playerId) => {
  const player = players.value.find(p => p.id === playerId)
  if (!player) return
  
  let totalArea = Math.PI * SPAWN_SAFE_RADIUS * SPAWN_SAFE_RADIUS // 初始安全区域面积
  
  // 计算所有领地面积
  for (const territory of player.territory) {
    totalArea += calculatePolygonArea(territory)
  }
  
  // 转换为百分比（相对于整个地图）
  const mapArea = canvasWidth * canvasHeight
  player.area = Math.round((totalArea / mapArea) * 100 * 100) / 100 // 保留2位小数
  
  // 更新分数（面积 * 10）
  player.score = Math.floor(player.area * 10)
}

// 更新连击计数
const updateCombo = () => {
  comboCount.value++
  
  // 计算连击倍数
  if (comboCount.value > 10) {
    comboMultiplier.value = 3
  } else if (comboCount.value > 5) {
    comboMultiplier.value = 2
  } else {
    comboMultiplier.value = 1
  }
  
  // 显示连击特效
  if (comboCount.value > 5) {
    showComboEffect.value = true
    setTimeout(() => {
      showComboEffect.value = false
    }, 1000)
  }
}

// ============= 游戏更新函数 =============

// 更新当前玩家小球
const updatePlayerBall = () => {
  // 游戏未开始时，玩家无法移动
  if (!gameStarted.value) return
  
  const player = currentPlayer.value
  if (!player || !player.isAlive) return
  
  let moveX = 0
  let moveY = 0
  
  // 根据按键计算移动方向
  if (keys.w) moveY -= 1
  if (keys.s) moveY += 1
  if (keys.a) moveX -= 1
  if (keys.d) moveX += 1
  
  // 标准化移动向量
  if (moveX !== 0 && moveY !== 0) {
    moveX *= 0.707
    moveY *= 0.707
  }
  
  // 计算当前速度
  let currentSpeed = player.ball.speed
  if (isBoosting.value && currentBoostTime.value > 0) {
    currentSpeed *= 2
    currentBoostTime.value--
    
    if (currentBoostTime.value <= 0) {
      isBoosting.value = false
      boostCooldown.value = 120
    }
  }
  
  // 更新冷却时间
  if (boostCooldown.value > 0) {
    boostCooldown.value--
  }
  
  // 更新无敌状态
  if (player.ball.isInvulnerable) {
    if (player.ball.invulnerabilityTime > 0) {
      player.ball.invulnerabilityTime--
      if (player.ball.invulnerabilityTime <= 0) {
        player.ball.isInvulnerable = false
      }
    }
    if (player.ball.semiInvulnerabilityTime > 0) {
      player.ball.semiInvulnerabilityTime--
    }
  }
  
  // 计算新位置
  const newX = player.ball.x + moveX * currentSpeed
  const newY = player.ball.y + moveY * currentSpeed
  
  // 边界检测 - 使用世界坐标系
  if (newX >= player.ball.radius && newX <= worldWidth.value - player.ball.radius &&
      newY >= player.ball.radius && newY <= worldHeight.value - player.ball.radius) {
    
    const newPos = { x: newX, y: newY }
    
    // 检查是否移动了
    if (moveX !== 0 || moveY !== 0) {
      // 获取领地状态
      const territoryStatus = getPlayerTerritoryStatus(currentUserId.value, newPos)
      
      // 如果还没有开始画线且不在自己领地内，检查是否可以开始画线
      if (!player.ball.isDrawing && !territoryStatus.inOwnTerritory) {
        // 检查是否可以在这个位置开始画线（不能在敌方领地内开始）
        if (canStartDrawingAt(currentUserId.value, newPos)) {
          player.ball.isDrawing = true
          player.ball.currentPath = [{ x: player.ball.x, y: player.ball.y }]
        } else {
          // 在敌方领地内不能开始画线，但可以移动（速度会降低）
          console.log('在敌方领地内，无法开始画线')
        }
      }
      
      // 如果从领地外移动到领地内，且正在画线，则完成圈地
      if (player.ball.isDrawing && territoryStatus.inOwnTerritory && player.ball.currentPath.length > 2) {
        // 检查起点是否在自己领地内
        const startPoint = player.ball.currentPath[0]
        const startInOwnTerritory = isPointInOwnTerritory(startPoint, currentUserId.value)
        
        if (startInOwnTerritory) {
          completeTerritory(currentUserId.value, player.ball.currentPath)
          player.ball.isDrawing = false
          player.ball.currentPath = []
        }
      }
      
      // 如果正在画线
      if (player.ball.isDrawing && gameStarted.value) { // 只有游戏开始后才检查线长
        // 检查线长限制 - 移除死亡惩罚，只是不继续画线
        const newPath = [...player.ball.currentPath, newPos]
        if (calculatePathLength(newPath) > MAX_LINE_LENGTH) {
          console.log('轨迹长度达到限制，请返回基地完成领地占领')
          // 不再杀死玩家，而是停止画线
          player.ball.isDrawing = false
          // 显示提示信息（可以考虑添加UI提示）
          return
        }
        
        player.ball.currentPath.push(newPos)
      } else if (player.ball.isDrawing && !gameStarted.value) {
        // 游戏开始前，只添加轨迹点而不检查限制
        player.ball.currentPath.push(newPos)
      }
      
      // 更新位置
      player.ball.x = newX
      player.ball.y = newY
      
      // 如果是当前玩家，更新摄像机跟随
      if (player.id === currentUserId.value && !dragging.isDragging) {
        updateCameraFollowPlayer(newX, newY)
      }
      
      // 更新移动距离统计
      paintedCells.value++
    }
  }
  
  // 优化的轨迹记录（减少频率以提升性能）
  const now = Date.now()
  if (!player.ball.lastTrailTime) player.ball.lastTrailTime = now
  
  // 只有当距离上次记录足够远或时间足够长时才记录
  const lastTrail = player.ball.trail[player.ball.trail.length - 1]
  const timeSinceLastTrail = now - player.ball.lastTrailTime
  const distanceSinceLastTrail = !lastTrail ? Infinity : 
    Math.sqrt((player.ball.x - lastTrail.x) ** 2 + (player.ball.y - lastTrail.y) ** 2)
  
  if (timeSinceLastTrail >= 16 && distanceSinceLastTrail >= 3) { // 约60FPS频率，3像素距离 - 更密集的路径记录
    player.ball.trail.push({
      x: player.ball.x,
      y: player.ball.y,
      timestamp: now
    })
    
    player.ball.lastTrailTime = now
    
    // 优化的轨迹长度管理
    if (player.ball.trail.length > 300) { // 减少轨迹长度
      player.ball.trail = player.ball.trail.slice(-300)
    }
  }
}

// ========= 战斗系统更新（性能优化版）=========
const updateBattleSystem = () => {
  if (!gameStarted.value) return // 游戏开始前不运行战斗系统
  
  // 性能优化：添加帧计数器，某些检查不需要每帧都做
  if (!updateBattleSystem.frameCounter) updateBattleSystem.frameCounter = 0
  updateBattleSystem.frameCounter++
  
  players.value.forEach(player => {
    // 处理死亡玩家的复活计时
    if (player.isDead) {
      player.respawnTimer--
      if (player.respawnTimer <= 0) {
        respawnPlayer(player.id)
      }
      return
    }
    
    if (!player.isAlive) return
    
    // 速度调整每5帧检查一次
    if (updateBattleSystem.frameCounter % 5 === 0) {
      adjustPlayerSpeed(player)
    }
    
    // 轨迹预警系统（仅对当前玩家，且降低频率）
    if (player.id === currentUserId.value) {
      checkTrajectoryWarning(player)
    }
    
    // 碰撞检测（只有在非无敌状态才会死亡）
    if (!player.ball.isInvulnerable) {
      let shouldDie = false
      let killerId = null
      
      // 检查与其他玩家的碰撞（每帧都检查，但优化算法）
      players.value.forEach(otherPlayer => {
        if (otherPlayer.id === player.id || !otherPlayer.isAlive || otherPlayer.isDead) return
        
        // 检查球体与轨迹碰撞
        if (checkBallTrajectoryCollision(player, otherPlayer)) {
          shouldDie = true
          killerId = otherPlayer.id
        }
        
        // 检查轨迹与轨迹相交（仅当两个玩家都在画线时）
        if (player.ball.isDrawing && otherPlayer.ball.isDrawing && checkTrajectoryCollision(player, otherPlayer)) {
          shouldDie = true
          killerId = otherPlayer.id
        }
      })
      
      // 移除自相交自杀机制 - 玩家只能被其他玩家击杀
      // 原来的自相交检查已被移除
      
      if (shouldDie) {
        killPlayer(player.id, killerId)
      }
    }
  })
}

// 更新其他玩家（AI）
const updateOtherPlayers = () => {
  // 游戏未开始时，AI玩家也无法移动
  if (!gameStarted.value) return
  
  players.value.forEach(player => {
    if (player.id !== currentUserId.value && player.isAlive) {
      // 更新无敌状态
      if (player.ball.isInvulnerable) {
        if (player.ball.invulnerabilityTime > 0) {
          player.ball.invulnerabilityTime--
          if (player.ball.invulnerabilityTime <= 0) {
            player.ball.isInvulnerable = false
          }
        }
        if (player.ball.semiInvulnerabilityTime > 0) {
          player.ball.semiInvulnerabilityTime--
        }
      }
      
      // 简单的AI移动逻辑
      const time = Date.now() * 0.001
      const seed = player.id.charCodeAt(player.id.length - 1)
      
      let angle = time * 0.5 + seed
      const speed = player.ball.speed
      
      let newX = player.ball.x + Math.cos(angle) * speed
      let newY = player.ball.y + Math.sin(angle) * speed
      
      // 边界检测 - 使用世界坐标系
      if (newX < player.ball.radius || newX > worldWidth.value - player.ball.radius) {
        newX = player.ball.x
      }
      if (newY < player.ball.radius || newY > worldHeight.value - player.ball.radius) {
        newY = player.ball.y
      }
      
      const newPos = { x: newX, y: newY }
      
      // AI移动逻辑
      const inOwnTerritory = isPointInOwnTerritory(newPos, player.id)
      
      if (!player.ball.isDrawing && !inOwnTerritory) {
        player.ball.isDrawing = true
        player.ball.currentPath = [{ x: player.ball.x, y: player.ball.y }]
      }
      
      if (player.ball.isDrawing && inOwnTerritory && player.ball.currentPath.length > 2) {
        const startPoint = player.ball.currentPath[0]
        const startInOwnTerritory = isPointInOwnTerritory(startPoint, player.id)
        
        if (startInOwnTerritory) {
          completeTerritory(player.id, player.ball.currentPath)
          player.ball.isDrawing = false
          player.ball.currentPath = []
        }
      }
      
      if (player.ball.isDrawing) {
        const newPath = [...player.ball.currentPath, newPos]
        if (calculatePathLength(newPath) > MAX_LINE_LENGTH * 0.8) {
          // AI不会画太长的线
          const spawnDirection = {
            x: player.spawnPoint.x - player.ball.x,
            y: player.spawnPoint.y - player.ball.y
          }
          const distance = Math.sqrt(spawnDirection.x * spawnDirection.x + spawnDirection.y * spawnDirection.y)
          if (distance > 0) {
            spawnDirection.x /= distance
            spawnDirection.y /= distance
            newX = player.ball.x + spawnDirection.x * speed * 2
            newY = player.ball.y + spawnDirection.y * speed * 2
          }
        } else {
          player.ball.currentPath.push(newPos)
        }
      }
      
      player.ball.x = newX
      player.ball.y = newY
      
      // 优化的AI轨迹记录
      const now = Date.now()
      if (!player.ball.lastTrailTime) player.ball.lastTrailTime = now
      
      const lastTrail = player.ball.trail[player.ball.trail.length - 1]
      const timeSinceLastTrail = now - player.ball.lastTrailTime
      const distanceSinceLastTrail = !lastTrail ? Infinity : 
        Math.sqrt((player.ball.x - lastTrail.x) ** 2 + (player.ball.y - lastTrail.y) ** 2)
      
      if (timeSinceLastTrail >= 50 && distanceSinceLastTrail >= 10) { // AI轨迹记录频率更低
        player.ball.trail.push({
          x: player.ball.x,
          y: player.ball.y,
          timestamp: now
        })
        
        player.ball.lastTrailTime = now
      }
      
      if (player.ball.trail.length > 1000) {
        player.ball.trail.splice(0, player.ball.trail.length - 1000)
      }
      
      // 更新统计
      updatePlayerStats(player.id)
    }
  })
}

// ============= 渲染函数 =============

// 绘制游戏
const drawGame = () => {
  if (!canvasCtx) return
  
  // 保存画布状态
  canvasCtx.save()
  
  // 应用摄像机变换
  canvasCtx.translate(-camera.x, -camera.y)
  
  // 清空画布背景（扩展到世界大小）
  canvasCtx.fillStyle = '#2c3e50'
  canvasCtx.fillRect(0, 0, worldWidth.value, worldHeight.value)
  
  // 绘制网格（基于世界坐标）
  if (gameSettings.showGrid) {
    canvasCtx.strokeStyle = 'rgba(255, 255, 255, 0.05)'
    canvasCtx.lineWidth = 1
    
    for (let x = 0; x <= worldWidth.value; x += 50) {
      canvasCtx.beginPath()
      canvasCtx.moveTo(x, 0)
      canvasCtx.lineTo(x, worldHeight.value)
      canvasCtx.stroke()
    }
    
    for (let y = 0; y <= worldHeight.value; y += 50) {
      canvasCtx.beginPath()
      canvasCtx.moveTo(0, y)
      canvasCtx.lineTo(worldWidth.value, y)
      canvasCtx.stroke()
    }
  }
  
  // 1. 使用高级合并技术绘制玩家领土（确保无边界问题）
  const tempCanvas = document.createElement('canvas')
  tempCanvas.width = worldWidth.value
  tempCanvas.height = worldHeight.value
  const tempCtx = tempCanvas.getContext('2d')
  
  players.value.forEach(player => {
    if (player.territory.length === 0) return
    
    // 清空临时画布
    tempCtx.clearRect(0, 0, worldWidth.value, worldHeight.value)
    
    // 设置颜色（纯色填充）
    tempCtx.fillStyle = player.color
    
    // 绘制出生点安全区域
    tempCtx.beginPath()
    tempCtx.arc(player.spawnPoint.x, player.spawnPoint.y, SPAWN_SAFE_RADIUS, 0, Math.PI * 2)
    tempCtx.fill()
    
    // 使用更好的路径绘制算法
    tempCtx.lineCap = 'round'
    tempCtx.lineJoin = 'round'
    
    // 绘制所有领土区域
    player.territory.forEach((territory, index) => {
      if (territory.type === 'filled' && territory.pixels) {
        // 高效渲染填充像素 - 使用ImageData批量处理
        renderFilledTerritoryOptimized(tempCtx, territory, player.color)
        
        // 绘制轮廓
        if (territory.outline && territory.outline.length > 0) {
          tempCtx.strokeStyle = player.color
          tempCtx.lineWidth = 3
          tempCtx.lineCap = 'round'
          tempCtx.lineJoin = 'round'
          tempCtx.beginPath()
          tempCtx.moveTo(territory.outline[0].x, territory.outline[0].y)
          for (let i = 1; i < territory.outline.length; i++) {
            tempCtx.lineTo(territory.outline[i].x, territory.outline[i].y)
          }
          tempCtx.closePath()
          tempCtx.stroke()
        }
      } else if (territory.type === 'path' && territory.points && territory.points.length >= 3) {
        // 传统路径渲染 - 深色，使用nonzero填充规则
        tempCtx.fillStyle = player.color
        tempCtx.strokeStyle = player.color
        tempCtx.lineWidth = 3
        tempCtx.lineCap = 'round'
        tempCtx.lineJoin = 'round'
        
        tempCtx.beginPath()
        tempCtx.moveTo(territory.points[0].x, territory.points[0].y)
        for (let i = 1; i < territory.points.length; i++) {
          tempCtx.lineTo(territory.points[i].x, territory.points[i].y)
        }
        tempCtx.closePath()
        tempCtx.fill('nonzero') // 使用nonzero填充规则处理复杂形状
        tempCtx.stroke()
      } else if (Array.isArray(territory) && territory.length >= 3) {
        // 兼容旧格式 - 深色，使用nonzero填充规则
        tempCtx.fillStyle = player.color
        tempCtx.strokeStyle = player.color
        tempCtx.lineWidth = 3
        tempCtx.lineCap = 'round'
        tempCtx.lineJoin = 'round'
        
        tempCtx.beginPath()
        tempCtx.moveTo(territory[0].x, territory[0].y)
        for (let i = 1; i < territory.length; i++) {
          tempCtx.lineTo(territory[i].x, territory[i].y)
        }
        tempCtx.closePath()
        tempCtx.fill('nonzero') // 使用nonzero填充规则处理复杂形状
        tempCtx.stroke()
      }
    })
    
    // 将合并后的结果绘制到主画布（无边界）
    canvasCtx.drawImage(tempCanvas, 0, 0)
  })
  
  // 3. 绘制出生点标识和边界
  
  // 2. 绘制出生点标识和边界（仅显示边界，不填充）
  players.value.forEach(player => {
    // 绘制出生点安全区域的边界指示（虚线）
    canvasCtx.strokeStyle = player.color
    canvasCtx.lineWidth = 2
    canvasCtx.setLineDash([8, 4])
    canvasCtx.beginPath()
    canvasCtx.arc(player.spawnPoint.x, player.spawnPoint.y, SPAWN_SAFE_RADIUS, 0, Math.PI * 2)
    canvasCtx.stroke()
    canvasCtx.setLineDash([]) // 重置虚线
    
    // 绘制出生点中心标识（发光效果）
    const centerGradient = canvasCtx.createRadialGradient(
      player.spawnPoint.x, player.spawnPoint.y, 0,
      player.spawnPoint.x, player.spawnPoint.y, 12
    )
    centerGradient.addColorStop(0, '#ffffff')
    centerGradient.addColorStop(0.3, player.color + 'FF')
    centerGradient.addColorStop(1, player.color + '00')
    
    canvasCtx.fillStyle = centerGradient
    canvasCtx.beginPath()
    canvasCtx.arc(player.spawnPoint.x, player.spawnPoint.y, 12, 0, Math.PI * 2)
    canvasCtx.fill()
    
    // 中心实心点
    canvasCtx.fillStyle = '#ffffff'
    canvasCtx.strokeStyle = player.color
    canvasCtx.lineWidth = 2
    canvasCtx.beginPath()
    canvasCtx.arc(player.spawnPoint.x, player.spawnPoint.y, 5, 0, Math.PI * 2)
    canvasCtx.fill()
    canvasCtx.stroke()
  })
  
  // 3. 绘制正在画的线条（美化轨迹效果，防止错误渲染）
  players.value.forEach(player => {
    if (player.ball.isDrawing && player.ball.currentPath.length > 1) {
      const isCurrentPlayer = player.id === currentUserId.value
      
      // 轨迹预警效果（当前玩家且有预警时）- 简化版本
      if (isCurrentPlayer && player.ball.pathWarning) {
        const time = Date.now() * 0.005 // 降低动画频率
        const warningAlpha = 0.6 + 0.4 * Math.sin(time)
        
        // 简化的预警效果，减少渲染计算
        canvasCtx.strokeStyle = `rgba(255, 50, 50, ${warningAlpha})`
        canvasCtx.lineWidth = TRAIL_WIDTH + 4
        canvasCtx.lineCap = 'round'
        canvasCtx.lineJoin = 'round'
        
        canvasCtx.beginPath()
        canvasCtx.moveTo(player.ball.currentPath[0].x, player.ball.currentPath[0].y)
        for (let i = 1; i < player.ball.currentPath.length; i++) {
          canvasCtx.lineTo(player.ball.currentPath[i].x, player.ball.currentPath[i].y)
        }
        canvasCtx.stroke()
      }
      
      // 优化的轨迹绘制（减少重复设置）
      const drawPath = (path, lineWidth, strokeStyle, offsetX = 0, offsetY = 0) => {
        canvasCtx.strokeStyle = strokeStyle
        canvasCtx.lineWidth = lineWidth
        canvasCtx.lineCap = 'round'
        canvasCtx.lineJoin = 'round'
        
        canvasCtx.beginPath()
        canvasCtx.moveTo(path[0].x + offsetX, path[0].y + offsetY)
        for (let i = 1; i < path.length; i++) {
          canvasCtx.lineTo(path[i].x + offsetX, path[i].y + offsetY)
        }
        canvasCtx.stroke()
      }
      
      // 绘制阴影
      drawPath(player.ball.currentPath, TRAIL_WIDTH + 4, 'rgba(0, 0, 0, 0.3)', 1, 1)
      
      // 绘制外层边框
      drawPath(player.ball.currentPath, TRAIL_WIDTH + 2, isCurrentPlayer ? '#ffffff' : 'rgba(255, 255, 255, 0.8)')
      
      // 绘制内层主色彩
      if (isCurrentPlayer) {
        // 为当前玩家添加发光效果
        canvasCtx.shadowColor = player.color
        canvasCtx.shadowBlur = 8
      }
      
      drawPath(player.ball.currentPath, TRAIL_WIDTH, player.color)
      
      // 重置阴影
      canvasCtx.shadowBlur = 0
      
      // 在轨迹上添加动态光点效果（仅当前玩家）
      if (isCurrentPlayer && player.ball.currentPath.length > 5) {
        const time = Date.now() * 0.005
        const dotCount = Math.min(8, player.ball.currentPath.length - 1)
        
        for (let i = 0; i < dotCount; i++) {
          const progress = (i / dotCount + time) % 1
          const pathIndex = Math.floor(progress * (player.ball.currentPath.length - 1))
          const point = player.ball.currentPath[pathIndex]
          
          if (point) {
            const alpha = 0.5 + 0.5 * Math.sin(time * 3 + i)
            canvasCtx.fillStyle = `rgba(255, 255, 255, ${alpha})`
            canvasCtx.beginPath()
            canvasCtx.arc(point.x, point.y, 3, 0, Math.PI * 2)
            canvasCtx.fill()
          }
        }
      }
      
      // 注意：这里不绘制填充区域，避免圈地过程中的错误渲染
    }
  })
  
  // 绘制玩家小球（增强视觉效果）
  players.value.forEach(player => {
    // 死亡玩家显示复活倒计时（游戏开始前强制不显示）
    if (player.isDead && gameStarted.value) {
      const respawnSeconds = Math.ceil(player.respawnTimer / 60)
      canvasCtx.fillStyle = 'rgba(255, 255, 255, 0.8)'
      canvasCtx.font = '16px Arial'
      canvasCtx.textAlign = 'center'
      canvasCtx.fillText(
        `${player.name} 复活中 ${respawnSeconds}s`,
        player.spawnPoint.x,
        player.spawnPoint.y - 30
      )
      
      // 绘制复活进度圈
      const progress = 1 - (player.respawnTimer / DEATH_RESPAWN_TIME)
      canvasCtx.strokeStyle = player.color
      canvasCtx.lineWidth = 3
      canvasCtx.beginPath()
      canvasCtx.arc(player.spawnPoint.x, player.spawnPoint.y, 20, -Math.PI / 2, -Math.PI / 2 + progress * 2 * Math.PI)
      canvasCtx.stroke()
      
      return
    }
    
    // 游戏开始前，强制重置死亡状态
    if (!gameStarted.value && player.isDead) {
      player.isDead = false
      player.isAlive = true
      player.respawnTimer = 0
    }
    
    if (!player.isAlive) return
    
    const ball = player.ball
    const isCurrentPlayer = player.id === currentUserId.value
    
    // 小球外发光效果
    if (isCurrentPlayer) {
      const glowGradient = canvasCtx.createRadialGradient(
        ball.x, ball.y, 0,
        ball.x, ball.y, ball.radius + 12
      )
      glowGradient.addColorStop(0, player.color + '60')
      glowGradient.addColorStop(0.5, player.color + '30')
      glowGradient.addColorStop(1, 'transparent')
      
      canvasCtx.fillStyle = glowGradient
      canvasCtx.beginPath()
      canvasCtx.arc(ball.x, ball.y, ball.radius + 12, 0, Math.PI * 2)
      canvasCtx.fill()
    }
    
    // 轨迹预警视觉反馈（当前玩家）- 简化版本
    if (isCurrentPlayer && ball.pathWarning) {
      const time = Date.now() * 0.01
      const warningAlpha = 0.6 + 0.4 * Math.sin(time)
      canvasCtx.strokeStyle = `rgba(255, 80, 80, ${warningAlpha})`
      canvasCtx.lineWidth = 2
      canvasCtx.beginPath()
      canvasCtx.arc(ball.x, ball.y, ball.radius + 6, 0, Math.PI * 2)
      canvasCtx.stroke()
    }
    
    // 小球阴影（非无敌状态）
    if (!ball.isInvulnerable) {
      canvasCtx.fillStyle = 'rgba(0, 0, 0, 0.4)'
      canvasCtx.beginPath()
      canvasCtx.arc(ball.x + 3, ball.y + 3, ball.radius, 0, Math.PI * 2)
      canvasCtx.fill()
    }
    
    // 无敌状态特效（改进）
    if (ball.isInvulnerable) {
      const time = Date.now() * 0.01
      const pulseRadius = ball.radius + 6 + Math.sin(time) * 3
      const pulseAlpha = 0.4 + 0.4 * Math.sin(time * 2)
      
      // 多层无敌光圈
      for (let i = 0; i < 3; i++) {
        canvasCtx.strokeStyle = `rgba(255, 255, 0, ${pulseAlpha / (i + 1)})`
        canvasCtx.lineWidth = 3 - i
        canvasCtx.beginPath()
        canvasCtx.arc(ball.x, ball.y, pulseRadius + i * 2, 0, Math.PI * 2)
        canvasCtx.stroke()
      }
    }
    
    // 小球主体（3D渐变效果）
    const ballGradient = canvasCtx.createRadialGradient(
      ball.x - ball.radius * 0.4, 
      ball.y - ball.radius * 0.4, 
      0,
      ball.x, 
      ball.y, 
      ball.radius * 1.2
    )
    ballGradient.addColorStop(0, '#ffffff')
    ballGradient.addColorStop(0.2, player.color + 'FF')
    ballGradient.addColorStop(0.6, player.color + 'CC')
    ballGradient.addColorStop(1, player.color + '88')
    
    canvasCtx.fillStyle = ballGradient
    canvasCtx.beginPath()
    canvasCtx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2)
    canvasCtx.fill()
    
    // 小球边框（双重边框）
    if (isCurrentPlayer) {
      // 外层白色边框
      canvasCtx.strokeStyle = '#ffffff'
      canvasCtx.lineWidth = 4
      canvasCtx.beginPath()
      canvasCtx.arc(ball.x, ball.y, ball.radius + 1, 0, Math.PI * 2)
      canvasCtx.stroke()
      
      // 内层彩色边框
      canvasCtx.strokeStyle = player.color
      canvasCtx.lineWidth = 2
      canvasCtx.beginPath()
      canvasCtx.arc(ball.x, ball.y, ball.radius - 1, 0, Math.PI * 2)
      canvasCtx.stroke()
    } else {
      canvasCtx.strokeStyle = '#ffffff'
      canvasCtx.lineWidth = 2
      canvasCtx.beginPath()
      canvasCtx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2)
      canvasCtx.stroke()
    }
    
    // 冲刺特效（改进）
    if (isCurrentPlayer && isBoosting.value) {
      const boostTime = Date.now() * 0.02
      for (let i = 0; i < 2; i++) {
        const radius = ball.radius + 8 + i * 4
        const alpha = 0.6 - i * 0.2
        canvasCtx.strokeStyle = `rgba(0, 255, 255, ${alpha})`
        canvasCtx.lineWidth = 3 - i
        canvasCtx.setLineDash([6, 6])
        canvasCtx.lineDashOffset = boostTime * (i + 1)
        canvasCtx.beginPath()
        canvasCtx.arc(ball.x, ball.y, radius, 0, Math.PI * 2)
        canvasCtx.stroke()
      }
      canvasCtx.setLineDash([]) // 重置虚线
      canvasCtx.lineDashOffset = 0
    }
    
    // 高光效果
    const highlightGradient = canvasCtx.createRadialGradient(
      ball.x - ball.radius * 0.3, 
      ball.y - ball.radius * 0.3, 
      0,
      ball.x - ball.radius * 0.3, 
      ball.y - ball.radius * 0.3, 
      ball.radius * 0.6
    )
    highlightGradient.addColorStop(0, 'rgba(255, 255, 255, 0.8)')
    highlightGradient.addColorStop(1, 'rgba(255, 255, 255, 0)')
    
    canvasCtx.fillStyle = highlightGradient
    canvasCtx.beginPath()
    canvasCtx.arc(ball.x - ball.radius * 0.3, ball.y - ball.radius * 0.3, ball.radius * 0.6, 0, Math.PI * 2)
    canvasCtx.fill()
    
    // 玩家名字（带阴影）
    canvasCtx.fillStyle = 'rgba(0, 0, 0, 0.5)'
    canvasCtx.font = 'bold 12px Arial'
    canvasCtx.textAlign = 'center'
    canvasCtx.fillText(player.name, ball.x + 1, ball.y - ball.radius - 7)
    
    canvasCtx.fillStyle = '#ffffff'
    canvasCtx.font = 'bold 12px Arial'
    canvasCtx.textAlign = 'center'
    canvasCtx.fillText(player.name, ball.x, ball.y - ball.radius - 8)
  })
  
  // 显示游戏开始倒计时
  if (!gameStarted.value && gameStartCountdown.value > 0) {
    // 恢复摄像机变换以在屏幕坐标系中绘制UI
    canvasCtx.restore()
    canvasCtx.save()
    
    const centerX = canvasWidth / 2
    const centerY = canvasHeight / 2
    
    // 绘制半透明背景
    canvasCtx.fillStyle = 'rgba(0, 0, 0, 0.7)'
    canvasCtx.fillRect(centerX - 150, centerY - 100, 300, 200)
    
    // 绘制倒计时数字
    canvasCtx.fillStyle = '#ffffff'
    canvasCtx.font = 'bold 72px Arial'
    canvasCtx.textAlign = 'center'
    canvasCtx.textBaseline = 'middle'
    canvasCtx.fillText(gameStartCountdown.value.toString(), centerX, centerY - 20)
    
    // 绘制提示文字
    canvasCtx.fillStyle = '#ffd700'
    canvasCtx.font = 'bold 24px Arial'
    canvasCtx.fillText('游戏即将开始', centerX, centerY + 40)
    
    // 重置文本对齐
    canvasCtx.textAlign = 'left'
    canvasCtx.textBaseline = 'alphabetic'
  }
  
  // 恢复摄像机状态
  canvasCtx.restore()
}

// 绘制迷你地图
const drawMinimap = () => {
  const ctx = minimapCanvas.value?.getContext('2d')
  if (!ctx) return
  
  // 计算缩放比例 - 基于世界坐标
  const scaleX = 150 / worldWidth.value
  const scaleY = 150 / worldHeight.value
  
  // 清空迷你地图
  ctx.fillStyle = '#34495e'
  ctx.fillRect(0, 0, 150, 150)
  
  // 绘制世界边界
  ctx.strokeStyle = '#666666'
  ctx.lineWidth = 1
  ctx.strokeRect(0, 0, 150, 150)
  
  // 绘制当前摄像机视角范围
  const viewportX = camera.x * scaleX
  const viewportY = camera.y * scaleY
  const viewportWidth = canvasWidth * scaleX
  const viewportHeight = canvasHeight * scaleY
  
  // 绘制视角框
  ctx.strokeStyle = '#00ff00'
  ctx.lineWidth = 1.5
  ctx.strokeRect(viewportX, viewportY, viewportWidth, viewportHeight)
  
  // 绘制半透明视角区域
  ctx.fillStyle = 'rgba(0, 255, 0, 0.15)'
  ctx.fillRect(viewportX, viewportY, viewportWidth, viewportHeight)
  
  // 绘制玩家占领的领土区域
  players.value.forEach(player => {
    if (player.territory.length === 0) return
    
    ctx.fillStyle = player.color // 使用完全不透明的颜色
    ctx.strokeStyle = player.color
    ctx.lineWidth = 1
    
    player.territory.forEach(territory => {
      if (territory.type === 'filled' && territory.pixels) {
        // 高效绘制填充像素（大幅减少显示像素）
        const step = Math.max(3, Math.floor(territory.pixels.length / 200))
        for (let i = 0; i < territory.pixels.length; i += step) {
          const pixel = territory.pixels[i]
          const miniX = pixel.x * scaleX
          const miniY = pixel.y * scaleY
          ctx.fillRect(miniX, miniY, Math.max(1, scaleX * 2), Math.max(1, scaleY * 2))
        }
      } else if (territory.type === 'path' && territory.points && territory.points.length >= 3) {
        // 绘制路径领土
        ctx.beginPath()
        for (let i = 0; i < territory.points.length; i++) {
          const point = territory.points[i]
          const miniX = point.x * scaleX
          const miniY = point.y * scaleY
          
          if (i === 0) {
            ctx.moveTo(miniX, miniY)
          } else {
            ctx.lineTo(miniX, miniY)
          }
        }
        ctx.closePath()
        ctx.fill()
        ctx.stroke()
      } else if (Array.isArray(territory) && territory.length >= 3) {
        // 兼容旧格式
        ctx.beginPath()
        for (let i = 0; i < territory.length; i++) {
          const point = territory[i]
          const miniX = point.x * scaleX
          const miniY = point.y * scaleY
          
          if (i === 0) {
            ctx.moveTo(miniX, miniY)
          } else {
            ctx.lineTo(miniX, miniY)
          }
        }
        ctx.closePath()
        ctx.fill()
        ctx.stroke()
      }
    })
  })
  
  // 绘制玩家当前轨迹
  players.value.forEach(player => {
    if (!player.ball.isDrawing || player.ball.currentPath.length < 2) return
    
    ctx.strokeStyle = player.color
    ctx.lineWidth = Math.max(1, TRAIL_WIDTH * scaleX)
    ctx.beginPath()
    
    for (let i = 0; i < player.ball.currentPath.length; i++) {
      const point = player.ball.currentPath[i]
      const miniX = point.x * scaleX
      const miniY = point.y * scaleY
      
      if (i === 0) {
        ctx.moveTo(miniX, miniY)
      } else {
        ctx.lineTo(miniX, miniY)
      }
    }
    
    ctx.stroke()
  })
  
  // 绘制出生点
  players.value.forEach(player => {
    const miniX = player.spawnPoint.x * scaleX
    const miniY = player.spawnPoint.y * scaleY
    const miniRadius = SPAWN_SAFE_RADIUS * scaleX
    
    ctx.fillStyle = player.color + '80'
    ctx.beginPath()
    ctx.arc(miniX, miniY, miniRadius, 0, Math.PI * 2)
    ctx.fill()
    
    ctx.fillStyle = '#ffffff'
    ctx.beginPath()
    ctx.arc(miniX, miniY, 2, 0, Math.PI * 2)
    ctx.fill()
  })
  
  // 绘制玩家位置
  players.value.forEach(player => {
    if (!player.isAlive) return
    
    const miniX = player.ball.x * scaleX
    const miniY = player.ball.y * scaleY
    
    ctx.fillStyle = player.color
    ctx.beginPath()
    ctx.arc(miniX, miniY, 3, 0, Math.PI * 2)
    ctx.fill()
  })
}

// ============= 游戏开始倒计时 =============
const startGameCountdown = () => {
  const countdownInterval = setInterval(() => {
    gameStartCountdown.value--
    
    if (gameStartCountdown.value <= 0) {
      clearInterval(countdownInterval)
      gameStarted.value = true
      
      // 初始化摄像机位置，跟随当前玩家
      const currentPlayer = players.value.find(p => p.id === currentUserId.value)
      if (currentPlayer) {
        updateCameraFollowPlayer(currentPlayer.ball.x, currentPlayer.ball.y)
      }
      
      console.log('游戏开始！')
    }
  }, 1000) // 每秒减少1
}

// ============= 游戏主循环（优化版，解决卡顿） =============

const startGameLoop = () => {
  let animationId = null
  let frameCount = 0
  
  const gameLoopFunction = () => {
    frameCount++
    
    // 更新游戏逻辑
    updatePlayerBall()
    updateOtherPlayers()
    
    // 每2帧更新一次战斗系统，减少计算频率
    if (frameCount % 2 === 0) {
      updateBattleSystem()
    }
    
    // 绘制游戏
    drawGame()
    
    // 每3帧更新一次小地图，进一步优化性能
    if (frameCount % 3 === 0) {
      drawMinimap()
    }
    
    // 使用requestAnimationFrame获得最佳性能
    animationId = requestAnimationFrame(gameLoopFunction)
  }
  
  // 保存游戏循环引用用于停止
  gameLoop = {
    stop: () => {
      if (animationId) {
        cancelAnimationFrame(animationId)
        animationId = null
      }
    }
  }
  
  // 启动游戏循环
  animationId = requestAnimationFrame(gameLoopFunction)
}

// ============= 事件处理 =============

const handleKeyDown = (event) => {
  const key = event.key.toLowerCase()
  
  switch (key) {
    case 'w':
      keys.w = true
      break
    case 'a':
      keys.a = true
      break
    case 's':
      keys.s = true
      break
    case 'd':
      keys.d = true
      break
    case ' ':
      event.preventDefault()
      if (!isBoosting.value && boostCooldown.value <= 0) {
        isBoosting.value = true
        currentBoostTime.value = maxBoostTime
      }
      break
  }
}

const handleKeyUp = (event) => {
  const key = event.key.toLowerCase()
  
  switch (key) {
    case 'w':
      keys.w = false
      break
    case 'a':
      keys.a = false
      break
    case 's':
      keys.s = false
      break
    case 'd':
      keys.d = false
      break
  }
}

// 鼠标事件处理 - 实现拖拽移动视角
const handleMouseDown = (event) => {
  dragging.isDragging = true
  dragging.startX = event.clientX
  dragging.startY = event.clientY
  dragging.lastCameraX = camera.x
  dragging.lastCameraY = camera.y
  
  // 改变鼠标样式
  if (gameCanvas.value) {
    gameCanvas.value.style.cursor = 'grabbing'
  }
}

const handleMouseMove = (event) => {
  if (!dragging.isDragging) return
  
  const deltaX = event.clientX - dragging.startX
  const deltaY = event.clientY - dragging.startY
  
  // 更新摄像机位置（注意方向相反，拖拽右移视角左移）
  camera.x = Math.max(0, Math.min(worldWidth.value - camera.width, dragging.lastCameraX - deltaX))
  camera.y = Math.max(0, Math.min(worldHeight.value - camera.height, dragging.lastCameraY - deltaY))
}

const handleMouseUp = () => {
  dragging.isDragging = false
  
  // 恢复鼠标样式
  if (gameCanvas.value) {
    gameCanvas.value.style.cursor = 'grab'
  }
}

const handleMinimapClick = (event) => {
  const rect = event.target.getBoundingClientRect()
  const x = event.clientX - rect.left
  const y = event.clientY - rect.top
  
  // 将迷你地图坐标转换为世界坐标
  const scaleX = worldWidth.value / 150
  const scaleY = worldHeight.value / 150
  
  const worldX = x * scaleX
  const worldY = y * scaleY
  
  // 移动摄像机到点击位置（居中）
  camera.x = Math.max(0, Math.min(worldWidth.value - camera.width, worldX - camera.width / 2))
  camera.y = Math.max(0, Math.min(worldHeight.value - camera.height, worldY - camera.height / 2))
}

// 摄像机跟随玩家
const updateCameraFollowPlayer = (playerX, playerY) => {
  // 将摄像机中心对准玩家位置
  const targetCameraX = playerX - camera.width / 2
  const targetCameraY = playerY - camera.height / 2
  
  // 限制摄像机在世界边界内
  camera.x = Math.max(0, Math.min(worldWidth.value - camera.width, targetCameraX))
  camera.y = Math.max(0, Math.min(worldHeight.value - camera.height, targetCameraY))
}

// ============= 游戏控制函数 =============

const formatTime = (seconds) => {
  const mins = Math.floor(seconds / 60)
  const secs = seconds % 60
  return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`
}

const startGameTimer = () => {
  gameInterval = setInterval(() => {
    if (gameTimer.value > 0) {
      gameTimer.value--
      
      if (gameTimer.value === 0) {
        endGame()
      }
    }
  }, 1000)
}

const resetCombo = () => {
  comboCount.value = 0
  comboMultiplier.value = 1
}

const leaveGame = () => {
  showLeaveConfirm.value = true
}

const confirmLeaveGame = () => {
  showLeaveConfirm.value = false
  router.push('/lobby')
}

const cancelLeaveGame = () => {
  showLeaveConfirm.value = false
}

const endGame = () => {
  clearInterval(gameInterval)
  if (gameLoop && gameLoop.stop) {
    gameLoop.stop()
  }
  router.push(`/game-result/${route.params.id}`)
}

// ============= 生命周期 =============

onMounted(() => {
  nextTick(() => {
    // 创建Canvas
    canvas = document.createElement('canvas')
    canvas.width = canvasWidth
    canvas.height = canvasHeight
    canvas.style.maxWidth = '100%'
    canvas.style.maxHeight = '100%'
    canvas.style.border = '1px solid rgba(255, 255, 255, 0.2)'
    canvas.style.borderRadius = '8px'
    canvas.tabIndex = 0
    
    // 添加事件监听
    canvas.addEventListener('keydown', handleKeyDown)
    canvas.addEventListener('keyup', handleKeyUp)
    
    // 获取Canvas上下文
    canvasCtx = canvas.getContext('2d')
    
    // 将Canvas添加到DOM
    if (gameCanvas.value) {
      gameCanvas.value.appendChild(canvas)
      canvas.focus()
    }
    
    // 初始化玩家统计和状态
    players.value.forEach(player => {
      updatePlayerStats(player.id)
      // 确保所有玩家开局时都是活着的状态
      player.isAlive = true
      player.isDead = false
      player.respawnTimer = 0
    })
    
    // 开始游戏计时器、倒计时和主循环
    startGameTimer()
    startGameCountdown() // 启动3秒倒计时
    startGameLoop()
  })
})

onUnmounted(() => {
  // 清理定时器
  if (gameInterval) {
    clearInterval(gameInterval)
  }
  
  if (gameLoop && gameLoop.stop) {
    gameLoop.stop()
  }
  
  // 清理事件监听
  if (canvas) {
    canvas.removeEventListener('keydown', handleKeyDown)
    canvas.removeEventListener('keyup', handleKeyUp)
  }
})
</script>
